package com.tn.service.alarm.impl;

import com.tn.controller.alarm.common.constants.Constants;
import com.tn.controller.alarm.common.model.PageInput;
import com.tn.controller.alarm.common.model.PageResult;
import com.tn.controller.alarm.common.model.alarm.entity.AlarmDO;
import com.tn.controller.alarm.common.model.alarm.entity.WorkAreaDO;
import com.tn.controller.alarm.common.model.alarm.vo.AlarmQueryVO;
import com.tn.controller.alarm.common.model.alarm.vo.AlarmVO;
import com.tn.controller.alarm.common.model.rpm.StaticFenceCheckParamDTO;
import com.tn.controller.alarm.common.model.vehicle.vo.AlarmInputParam;
import com.tn.dao.alarm.IAlarmDao;
import com.tn.service.alarm.IAlarmService;
import com.tn.service.rpm.RpmServeService;
import com.tn.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 告警service实现类
 *
 * @program: tn_aucy_java
 * @author: yangjiayao
 * @create: 2022/2/17
 */
@Service
public class AlarmServiceImpl implements IAlarmService {
    /**
     * 单位坐标的实际长度（米）
     */
    @Value("${alarm.coordinateUnit}")
    private double coordinateUnit;

    /**
     * 告警数据访问层
     */
    private IAlarmDao alarmDao;

    /**
     * 告警service
     */
    private RpmServeService rpmServeService;

    /**
     * 注入
     *
     * @param alarmDao alarmDao
     */
    @Autowired
    public void setAlarmDao(IAlarmDao alarmDao) {
        this.alarmDao = alarmDao;
    }

    /**
     * 注入
     *
     * @param rpmServeService rpmServeService
     */
    @Autowired
    public void setRpmServeService(RpmServeService rpmServeService) {
        this.rpmServeService = rpmServeService;
    }

    @Override
    public Map<String, String> queryAlarmParam() {
        Map<String, String> param = new HashMap<>();
        param.put(Constants.ALARM_PARAM, alarmDao.queryAlarmParam(Constants.ALARM_PARAM));
        return param;
    }

    @Override
    public boolean updateAlarmParam(String name, String value) {
        int num = alarmDao.updateAlarmParam(name, value);
        if (1 > num) {
            num = alarmDao.insertAlarmParam(name, value);
        }
        return 0 < num;
    }

    @Override
    public PageResult<AlarmVO> queryAlarmInfo(PageInput<AlarmQueryVO> alarmPageQuery) {
        int total = alarmDao.queryAlarmCount(alarmPageQuery.getData());
        PageResult<AlarmVO> result = new PageResult<>(alarmPageQuery.getCurPage(), alarmPageQuery.getPageSize(), total);
        if (0 < total) {
            result.setData(alarmDao.queryAlarmByPage(result.getStartIndex(), alarmPageQuery.getPageSize(),
                    alarmPageQuery.getData()));
        }
        return result;
    }

    @Override
    public int saveAlarmInfo(AlarmInputParam alarmParam) {
        AlarmDO alarmDO = new AlarmDO();
        alarmDO.setTagId(alarmParam.getTagId());
        alarmDO.setLicense(alarmParam.getLicense());
        alarmDO.setTallyTaskNo(alarmParam.getTallyTaskNo());
        return alarmDao.insertAlarmInfo(alarmDO);
    }

    @Override
    public boolean handleAlarm(String handler, Integer id) {
        AlarmDO alarmEntity = new AlarmDO(id, handler, DateUtil.dateToString(new Date()));
        int num = alarmDao.handleAlarm(alarmEntity);
        return 0 < num;
    }

    @Override
    public int createAlarmTask(AlarmInputParam alarmParam) {
        if (StringUtils.isNotBlank(alarmParam.getStoreHouse()) && StringUtils.isNotBlank(alarmParam.getLocation())
                && StringUtils.isNotBlank(alarmParam.getTagId())) {
            String[] locations = alarmParam.getLocation().split(Constants.POSITION_DIVISION_SYMBOL);
            if (1 < locations.length) {
                WorkAreaDO workArea = alarmDao.queryWorkArea(alarmParam.getStoreHouse());
                if (StringUtils.isNotBlank(workArea.getPosition())) {
                    String deviationStr = alarmDao.queryAlarmParam(Constants.ALARM_PARAM);
                    double deviation = 0;
                    if (StringUtils.isNotBlank(deviationStr)) {
                        deviation = Double.parseDouble(deviationStr);
                    }
                    String eleFencePosition = calEleFence(workArea.getPosition(), Double.parseDouble(locations[0]),
                            Double.parseDouble(locations[1]), deviation);
                    Map<String, String> fenceList = new HashMap<>();
                    fenceList.put("1", eleFencePosition);
                    return rpmServeService.sendStaticFenceCheck(StaticFenceCheckParamDTO.builder().fenceList(fenceList)
                            .taglist(Collections.singletonList(alarmParam.getTagId())).dimention(2).floor("1")
                            .fenceshape("polygon").direction(Constants.DETECTION_TASK_DIRECTION).build());
                }
            }
        }
        return -1;
    }

    @Override
    public void deleteAlarmTask(Integer alarmTaskId) {
        if (null != alarmTaskId) {
            rpmServeService.deleteStaticFenceCheck(alarmTaskId);
        }
    }

    /**
     * 计算围栏坐标
     *
     * @param workAreaPosition 库场坐标
     * @param start            货位开始值
     * @param end              货位结束值
     * @param deviation        偏移量
     * @return 围栏坐标
     */
    private String calEleFence(String workAreaPosition, double start, double end, double deviation) {
        String[] points = workAreaPosition.split(Constants.POSITION_DIVISION_SYMBOL);
        double yMin = Double.parseDouble(points[7]) - deviation / coordinateUnit;
        double yMax = Double.parseDouble(points[1]) + deviation / coordinateUnit;
        double xMin = Double.parseDouble(points[0]) + (start - deviation) / coordinateUnit;
        double xMax = Double.parseDouble(points[0]) + (end + deviation) / coordinateUnit;
        return xMin + Constants.POSITION_DIVISION_SYMBOL + yMax + Constants.POSITION_DIVISION_SYMBOL +
                xMax + Constants.POSITION_DIVISION_SYMBOL + yMax + Constants.POSITION_DIVISION_SYMBOL +
                xMax + Constants.POSITION_DIVISION_SYMBOL + yMin + Constants.POSITION_DIVISION_SYMBOL +
                xMin + Constants.POSITION_DIVISION_SYMBOL + yMin + Constants.POSITION_DIVISION_SYMBOL +
                xMin + Constants.POSITION_DIVISION_SYMBOL + yMax;
    }

    public void addAlarm() {
    }
}
